import requests
import json
from quant.exchanges.util import spot_value_factor, Socket, AscendingChecker, RecentChecker, NullCls
from quant.exchanges.basics import *
from quant.exchanges._factory import add_factory
from quant.const import *



class GdaxChannel(ChannelBasic):
    def init(self):
        host = ws_host
        self.socket = Socket(host, self.on_open, self.on_message, self.on_close)

    def subscribe_book(self, ws):
        symbol = self.symbol.replace('/', '-').upper()

        # if self.frequency == DataFrequency.High:
        #     event = {'type': 'subscribe', 'product_ids': [symbol], 'channels': ['level2']}
        # else:
        #     event = {'type': 'subscribe', 'product_ids': [symbol], 'channels': ['ticker']}
        event = {'type': 'subscribe', 'product_ids': [symbol], 'channels': ['ticker']}

        message = json.dumps(event)
        ws.send(message)

    def subscribe_trade(self, ws):
        symbol = self.symbol.replace('/', '-').upper()
        event = {'type': 'subscribe', 'product_ids': [symbol], 'channels': ['matches']}
        message = json.dumps(event)
        ws.send(message)


class GdaxHandler(HandlerBasic):
    def init(self):
        self.data_id_checker = RecentChecker(50)

    def process_book(self, routing_key, recv_time, raw):
        if raw == NAME_CHANNEL_CLOSE:
            return self.process_close(routing_key, recv_time)

        data = json.loads(raw)
        if data['type'] == 'subscriptions':
            return self.info_welcome()

        server_id = data['sequence']
        if not self.data_id_checker.is_new(server_id):
            return

        server_time = None
        book = self.book
        book['buy'] = [[float(data['best_bid']), 0.0001]]
        book['sell'] = [[float(data['best_ask']), 0.0001]]

        # self.check_book(book)
        self.push_book(routing_key, recv_time, server_time, server_id, book)

    def process_trade(self, routing_key, recv_time, raw):
        if raw == NAME_CHANNEL_CLOSE:
            return self.process_close(routing_key, recv_time)

        data = json.loads(raw)
        if data['type'] == 'subscriptions':
            return self.info_welcome()

        server_id = data['sequence']
        if not self.data_id_checker.is_new(server_id):
            return

        server_time = None
        trade_list = [[opposite[data['side']], float(data['price']), float(data['size'])]]

        self.push_trade(routing_key, recv_time, server_time, server_id, trade_list)


class GdaxApi(NullCls):
    pass


class GdaxSpi(NullCls):
    pass


class GdaxFunctions(Functions):
    def get_value_factor(self, symbol):
        return spot_value_factor(symbol)


ws_host = 'wss://ws-feed.pro.coinbase.com'
opposite = {'buy': 'sell', 'sell': 'buy'}
add_factory(Exchange.Gdax, GdaxChannel, GdaxHandler, GdaxApi, GdaxSpi, GdaxFunctions)


if __name__ == '__main__':
    from quant.markets import Markets
    from quant.const import Event, Exchange
    from utils import print_book, print_trades

    mar = Markets()
    mar.add_market(Event.Trade, Exchange.Gdax, 'eos/usd')
    print_trades(mar)

    input(':')


















